<template>
  <view v-if="pageData.isError">当前无法使用录音</view>
  <view v-else :class="pageData.longPress == '1' ? 'record-layer' : 'record-layer1'">
    <view :class="pageData.longPress == '1' ? 'record-box' : 'record-box1'">
      <view class="tips" v-if="pageData.longPress != 1">
        <view class="chatIcon icon-shanghua1"></view>
        <view>上滑取消发送</view>
      </view>
      <view class="record-btn-layer">
        <button
          class="record-btn"
          :class="pageData.longPress == '1' ? 'record-btn-1' : 'record-btn-2'"
          :style="waveBtnStyle"
          @longtap="longpressBtn"
          @touchend="touchendBtn()"
          @touchmove="handleTouchMove"
          @touchstart="longpressBtn"
        >
          <!-- <text class="chatIcon icon-yuyin" style="font-size: 50rpx; margin-right: 10rpx"></text> -->
          <text style="font-size: 30rpx">{{ pageData.VoiceText }}</text>
        </button>
      </view>
      <!-- 语音音阶动画 -->
      <view
        :class="
          pageData.VoiceTitle != '松开手指,取消发送' ? 'prompt-layer prompt-layer-1' : 'prompt-layer1 prompt-layer-1'
        "
        v-if="pageData.longPress == '2'"
      >
        <view class="prompt-loader">
          <view class="em" v-for="(item, index) in 15" :key="index"></view>
        </view>
        <text class="span">{{ pageData.VoiceTitle }}</text>
      </view>
    </view>
  </view>
</template>
<script setup>
import recorder from "../../utils/recorder";
import { computed, reactive, onMounted, ref } from "vue";

const pageData = reactive({
  longPress: "1", // 1显示 按住 说话 2显示 说话中
  delShow: false, // 删除提示框显示隐藏
  time: 0, //录音时长
  duration: 60000, //录音最大值ms 60000/1分钟
  tempFilePath: "", //音频路径
  startPoint: {}, //记录长按录音开始点信息,用于后面计算滑动距离。
  sendLock: true, //发送锁，当为true时上锁，false时解锁发送
  VoiceTitle: "松手结束录音",
  // recorderManager: recorder,
  VoiceText: "按住 说话",
  types: "",
  // 录音初始化失败
  isError: false,
});

const waveBtnStyle = computed(() => {
  if (pageData.VoiceText == "按住 说话") return "background-color: #f5f5f5;color:grey;";
  else if (pageData.longPress == "2" && ["松开手指,取消发送"].includes(pageData.VoiceText))
    return "background-image: linear-gradient(to top, #ff6060 0%, rgb(255 255 255 / 0%) 100%);color:white;";
  else if (pageData.longPress == "1" || ["松手结束录音", "说话中..."].includes(pageData.VoiceText))
    return "background-image: linear-gradient(to top, #95eb6c 0%, rgb(255 255 255 / 0%) 100%);color:white";
  else return "background-color: #f5f5f5;color:grey;";
});

// 长按录音事件
function longpressBtn(e) {
  pageData.startPoint = e.touches[0]; //记录长按时开始点信息，后面用于计算上划取消时手指滑动的距离。
  pageData.longPress = "2";
  pageData.VoiceText = "说话中...";

  const options = {
    duration: pageData.duration, // 指定录音的时长，单位 ms
    sampleRate: 16000, // 采样率
    numberOfChannels: 1, // 录音通道数
    encodeBitRate: 96000, // 编码码率
    format: "mp3", // 音频格式，有效值 aac/mp3
    frameSize: 10, // 指定帧大小，单位 KB
  };
  recorder.recStart(options);
  // 监听音频开始事件
  pageData.sendLock = false; //长按时是不上锁的。
  // recorder.onStart((res) => {});
}
// 长按松开录音事件
function touchendBtn() {
  pageData.longPress = "1";
  pageData.VoiceText = "按住 说话";
  pageData.VoiceTitle = "松手结束录音";

  // this.recordingTimer(this.time)
  recorder.recStop(); //结束录音
  pageData.longPress = "1";
}
// 删除录音
function handleTouchMove(e) {
  //touchmove时触发
  let moveLenght = e.touches[e.touches.length - 1].clientY - pageData.startPoint.clientY; //移动距离
  if (Math.abs(moveLenght) > 70) {
    // console.log("松开手指,取消发送");
    pageData.VoiceTitle = "松开手指,取消发送";
    pageData.VoiceText = "松开手指,取消发送";
    delBtn();
    pageData.sendLock = true; //触发了上滑取消发送，上锁
  } else {
    pageData.VoiceTitle = "松手结束录音";
    pageData.VoiceText = "松手结束录音";
    pageData.sendLock = false; //上划距离不足，依然可以发送，不上锁
  }
}
function delBtn() {
  pageData.delShow = false;
  pageData.time = 0;
  pageData.tempFilePath = "";
  // this.VoiceTitle = '松手结束录音'
}

const emits = defineEmits(["onEnd"]);

onMounted(async () => {
  pageData.isError = false;
  try {
    // recOpen() 调用open打开录音请求好录音权限*
    await recorder.recOpen();
    recorder.onStop((res) => {
      // console.warn("  recorder.onStop ", res);
      switch (pageData.longPress) {
        case "1":
          console.log(pageData.sendLock);
          //上锁不发送
          if (pageData.sendLock) return;

          //解锁发送，发送网络请求
          if (res.duration < 1000) {
            uni.showToast({
              title: "录音时间太短",
              icon: "error",
              duration: 1000,
            });
          } else {
            pageData.tempFilePath = res.tempFilePath;
            // 文件上传
            emits("onEnd", {
              ...res,
              longPress: pageData.longPress,
              tempFilePath: res.tempFilePath,
              url: res.localUrl,
              file: res.blod,
            });
          }
          break;
        case "2":
          pageData.tempFilePath = res.tempFilePath;

          break;
        default:
          break;
      }
    });
  } catch {
    uni.showToast({
      title: "无法开启录音",
      icon: "error",
    });
    pageData.isError = true;
  }
});
</script>
<style lang="scss" scoped>
/* 语音录制开始--------------------------------------------------------------------- */
.record-layer {
  box-sizing: border-box;
  z-index: 999999;
}

.record-layer1 {
  width: 100vw;
  box-sizing: border-box;
  height: 100vh;
  position: fixed;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 999999;
  top: 0;
  bottom: 0vh;
  left: 0;
  backdrop-filter: blur(10px);
}

.record-box {
  width: 100%;
  position: relative;
}

.record-btn {
  background-color: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  // flex-direction: column;
}
.tips {
  position: absolute;
  bottom: 80rpx;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  color: #ffffff80;

  .chatIcon {
    font-size: 50rpx;
    margin-right: 20rpx;
  }
}

.record-box1 {
  width: 100%;
  position: relative;
  bottom: calc(150rpx - 100%);
  // height: 17vh;
}
.record-btn-layer {
  width: 100%;
}

.record-btn-layer button::after {
  border: none;
  transition: all 0.1s;
}

.record-btn-layer button {
  font-size: 14px;
  line-height: inherit;
  width: 100%;
  // height: 50px;
  border-radius: 8px;
  text-align: center;
  // background: #ffd300;
  transition: all 0.1s;
}

.record-btn-layer button image {
  width: 16px;
  height: 16px;
  margin-right: 4px;
  vertical-align: middle;
  transition: all 0.3s;
}
.record-btn-layer .record-btn-1 {
  // background-image: linear-gradient(to right, #43e97b 0%, #38f9d7 100%);
  // background: #f5f5f5;
  color: #000000 !important;
}

.record-btn-layer .record-btn-2 {
  // border-radius: 50%;
  // border-bottom-right-radius: 0;
  // border-bottom-left-radius: 0;
  // border-top: 5px solid white;
  height: 150rpx;
  line-height: 150rpx;
  transition: all 0.3s;
}

/* 提示小弹窗 */
.prompt-layer {
  border-radius: 15px;
  // background: #95eb6c;
  background: #fafafa;
  padding: 8px 16px;
  box-sizing: border-box;
  position: absolute;
  left: 50%;
  height: 11vh;
  transform: translateX(-50%);
  transition: all 0.3s;
}

.prompt-layer::after {
  content: "";
  display: block;
  border: 12px solid rgba(0, 0, 0, 0);
  border-radius: 10rpx;
  // border-top-color: #95eb6c;
  border-top-color: #fafafa;
  position: absolute;
  bottom: -40rpx;
  left: 50%;
  transform: translateX(-50%);
  transition: all 0.3s;
}
//取消动画
.prompt-layer1 {
  border-radius: 15px;
  background: #fb5353;
  padding: 8px 16px;
  box-sizing: border-box;
  position: absolute;
  left: 50%;
  height: 11vh;
  transform: translateX(-50%);
  transition: all 0.3s;
}

.prompt-layer1::after {
  content: "";
  display: block;
  border: 12px solid rgba(0, 0, 0, 0);
  border-radius: 10rpx;
  border-top-color: #fb5353;
  position: absolute;
  bottom: -40rpx;
  left: 50%;
  transform: translateX(-50%);
  transition: all 0.3s;
}
.prompt-layer-1 {
  font-size: 12px;
  width: 150px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  top: -400rpx;
}

.prompt-layer-1 .p {
  color: #000000;
}

.prompt-layer-1 .span {
  color: rgba(0, 0, 0, 0.6);
}

/* 语音音阶------------- */
.prompt-loader {
  width: 96px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.prompt-loader .em {
  display: block;
  background: #5a5a5a;
  width: 5px;
  height: 10%;
  margin-right: 2.5px;
  border-radius: 99rpx;
  float: left;
}

.prompt-loader .em:last-child {
  margin-right: 0px;
}

.prompt-loader .em:nth-child(1) {
  animation: load 2.5s 1.4s infinite linear;
}

.prompt-loader .em:nth-child(2) {
  animation: load 2.5s 1.2s infinite linear;
}

.prompt-loader .em:nth-child(3) {
  animation: load 2.5s 1s infinite linear;
}

.prompt-loader .em:nth-child(4) {
  animation: load 2.5s 0.8s infinite linear;
}

.prompt-loader .em:nth-child(5) {
  animation: load 2.5s 0.6s infinite linear;
}

.prompt-loader .em:nth-child(6) {
  animation: load 2.5s 0.4s infinite linear;
}

.prompt-loader .em:nth-child(7) {
  animation: load 2.5s 0.2s infinite linear;
}

.prompt-loader .em:nth-child(8) {
  animation: load 2.5s 0s infinite linear;
}

.prompt-loader .em:nth-child(9) {
  animation: load 2.5s 0.2s infinite linear;
}

.prompt-loader .em:nth-child(10) {
  animation: load 2.5s 0.4s infinite linear;
}

.prompt-loader .em:nth-child(11) {
  animation: load 2.5s 0.6s infinite linear;
}

.prompt-loader .em:nth-child(12) {
  animation: load 2.5s 0.8s infinite linear;
}

.prompt-loader .em:nth-child(13) {
  animation: load 2.5s 1s infinite linear;
}

.prompt-loader .em:nth-child(14) {
  animation: load 2.5s 1.2s infinite linear;
}

.prompt-loader .em:nth-child(15) {
  animation: load 2.5s 1.4s infinite linear;
}

@keyframes load {
  0% {
    height: 10%;
  }

  50% {
    height: 100%;
  }

  100% {
    height: 10%;
  }
}

/* 语音音阶-------------------- */
.prompt-layer-2 {
  top: -40px;
}

.prompt-layer-2 .text {
  color: rgba(0, 0, 0, 1);
  font-size: 12px;
}

/* 语音录制结束---------------------------------------------------------------- */
</style>
